package com.tangruojie.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String userName;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }

    /**
     * Spring 底层默认使用的是 JDBC 事务（基于本地事务），具体实现是通过 DataSourceTransactionManager 来完成的。
     * MyBatis 默认使用的是 JDBC 事务（JdbcTransaction），它是基于原生 JDBC Connection 来进行事务控制的。
     * ---------
     * MyBatis 与 Spring 整合后事务策略变化
     * 当你使用了 MyBatis-Spring（SqlSessionTemplate）+ Spring 事务管理器（如 DataSourceTransactionManager） 时：
     * 1、MyBatis 会自动切换为使用 Spring 提供的事务（不是 JdbcTransaction）
     * 2、SqlSession 会复用当前线程绑定的 Connection
     * 3、实际事务提交、回滚由 Spring 控制
     */

    /**
     * Spring 支持多种事务管理器，取决于你的项目依赖：
     * 场景	                    使用的 TransactionManager
     * JDBC / MyBatis	        DataSourceTransactionManager
     * JPA	                    JpaTransactionManager
     * Hibernate	            HibernateTransactionManager
     * 分布式事务（JTA）	        JtaTransactionManager
     * 使用 Atomikos	            AtomikosTransactionManager
     * Spring 并不强制用 JDBC，而是根据你注入的 TransactionManager 类型来选择。
     */

    /**
     * 配置事务管理器，mybatis使用的是jdbc事务
     *
     * @param dataSource
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource);
        return transactionManager;
    }

}